<template>
  <tm-overlay v-model:show="isVisible" contentAnimation @update:show="onVisibleChange">
    <view @click.stop>
      <tm-sheet :width="650" :round="4" :margin="[32, 32]" :padding="[0, 0]">
        <tm-sheet :margin="[0, 0]" :padding="[24, 12]" _class="flex-row flex-between">
          <tm-text _class="text-overflow-1" :font-size="28" :label="fileName"></tm-text>
          <tm-icon @click="close" :font-size="32" name="tmicon-times"></tm-icon>
        </tm-sheet>
        <tm-divider :margin="[0, 0]"></tm-divider>
        <scroll-view scroll-y :style="{ height: '70vh', 'max-height': '70vh' }">
          <view class="code-wrapper">
            <pre><code :class="languageClass" v-html="highlightedCode"></code></pre>
          </view>
        </scroll-view>
      </tm-sheet>
    </view>
  </tm-overlay>
</template>

<script lang="ts" setup>
import { ref, computed, watch, toRefs } from 'vue';
import hljs from 'highlight.js/lib/core'; // 只引入核心库
// 按需引入需要的语言支持
import javascript from 'highlight.js/lib/languages/javascript';
import typescript from 'highlight.js/lib/languages/typescript';
import xml from 'highlight.js/lib/languages/xml'; // HTML, Vue template
import css from 'highlight.js/lib/languages/css';
import json from 'highlight.js/lib/languages/json';
import java_ from 'highlight.js/lib/languages/java'; // 使用 java_ 避免关键字冲突
import markdown from 'highlight.js/lib/languages/markdown';

// 注册语言
hljs.registerLanguage('javascript', javascript);
hljs.registerLanguage('typescript', typescript);
hljs.registerLanguage('xml', xml); // 用于 html, vue
hljs.registerLanguage('css', css);
hljs.registerLanguage('json', json);
hljs.registerLanguage('java', java_);
hljs.registerLanguage('markdown', markdown); // 如果需要支持 .md

const props = defineProps<{
  visible: boolean;
  fileName: string;
  content: string;
  extension: string;
}>();

const emit = defineEmits(['update:visible']);

const { visible, fileName, content, extension } = toRefs(props);
const isVisible = ref(visible.value);

watch(visible, (newVal) => {
  isVisible.value = newVal;
});

const onVisibleChange = (val: boolean) => {
  emit('update:visible', val);
};

const close = () => {
  emit('update:visible', false);
};

const languageClass = computed(() => {
  const extMap: Record<string, string> = {
    '.vue': 'xml', // Vue template 部分用 xml 高亮
    '.tsx': 'typescript',
    '.jsx': 'javascript',
    '.js': 'javascript',
    '.json': 'json',
    '.html': 'xml',
    '.java': 'java',
    '.ts': 'typescript',
    '.css': 'css',
    '.scss': 'css', // scss 可以用 css 高亮
    '.md': 'markdown',
  };
  const lang = extMap[extension.value] || 'plaintext'; // 默认为纯文本
  return `hljs ${lang}`; // highlight.js 需要 'hljs' 类和语言类
});

const highlightedCode = computed(() => {
  if (!content.value) {
    return '';
  }
  try {
    // 尝试根据推断的语言高亮，如果失败则作为纯文本高亮
    const lang = languageClass.value.split(' ')[1]; // 获取语言名称
    if (hljs.getLanguage(lang)) {
      return hljs.highlight(content.value, { language: lang }).value;
    } else {
      return hljs.highlight(content.value, { language: 'plaintext' }).value;
    }
  } catch (e) {
    console.error('Highlighting error:', e);
    return content.value.replace(/</g, '&lt;').replace(/>/g, '&gt;');
  }
});
</script>

<style lang="scss" scoped>
/* 引入的 highlight.js 样式会应用到 <code> 标签 */
.code-wrapper {
  padding: 20rpx;
  background-color: #f8f8f8; // 可以根据 highlight.js 主题调整背景色
  overflow: auto; // 确保内容可滚动
  font-family: monospace; // 使用等宽字体
  font-size: 24rpx; // 调整字体大小
  line-height: 1.5; // 调整行高

  pre {
    margin: 0; // 去除 pre 标签的默认 margin
    white-space: pre; // 保留代码中的空格和换行
    word-wrap: normal; // 防止自动换行，允许水平滚动
  }

  code.hljs {
    display: block; // 让 code 块充满 pre
    min-width: 100%; // 确保内容宽度至少为容器宽度
    width: fit-content; // 内容自适应宽度
    padding: 0; // highlight.js 默认有 padding，如果需要可以覆盖
    background: none; // 通常不需要单独背景，依赖 .code-wrapper 或主题样式
    border-radius: 0; // 如果主题有圆角，可以覆盖
  }
}
</style>